package com.naiterui.ehp.bs.doctor.utils.message;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.naiterui.ehp.bp.support.exception.BusinessException;
import com.naiterui.ehp.bs.doctor.exception.ExceptionCodes;
import com.naiterui.ehp.bs.doctor.prodocl.Education;
import com.naiterui.ehp.bs.doctor.prodocl.Message;

import lombok.extern.slf4j.Slf4j;


/**
 * 负责消息编码与解码的逻辑处理类
 * 根据消息类型绑定了不同的编解码处理器
 * 具体的数据于对象间的转换交由底层处理
 * <P>File name : MessageTransCoder.java </P>
 * <P>Author : zhouyanxin </P>
 * <P>Date : 2015年6月22日 </P>
 */
@Service
@Slf4j
public class MessageTransCoder<T> implements IMessageTransCoder {

    /**
     * 文本消息编解码器
     */
    @Autowired
    @Qualifier(value = "textMsgTransCoder")
    private AbstractTransCoder<String> textTransCoder;

    /**
     * 宣教消息
     */
    @Autowired
    @Qualifier(value = "eduMsgTransCoder")
    private AbstractTransCoder<Education> eduMsgTransCoder;


    /**
     * 消息解码
     * 用于将从客户端传递来的消息转换为指定消息类型对应的对象
     * 转换完成后会对消息的完整性和正确性进行检测
     * MessageTransCoder.decodeMessage()<BR>
     * <P>Author : zhouyanxin </P>
     * <P>Date : 2015年6月22日 </P>
     *
     * @param message
     *
     * @return
     */
    @Override
    public Message<?> decodeMessage(String message) throws BusinessException {

        // 解析消息类型
        Integer messageType = null;
        try {
            messageType = (JSON.parseObject(message)).getInteger("type");
        } catch (Exception e) {
            log.error("message is not a available json format! message is {}", message);
            throw new BusinessException(ExceptionCodes.MSG_FORMAT_INVALID, e);
        }

        // 消息构建不正确缺少必要的类型参数
        if (messageType == null) {
            log.error("not found attribute [type] in message body! message is {}", message);
            throw new BusinessException(ExceptionCodes.MSG_FORMAT_INVALID);
        }

        // 消息对象
        Message<?> messageObj = null;

        // 根据类型反序列化消息信息
        if (messageType == Constants.MESSAGE_TYPE_TEXT) {
            messageObj = this.textTransCoder.deserializeMessage(message);
        } else if (messageType == Constants.MESSAGE_TYPE_EDU) {
            messageObj = this.eduMsgTransCoder.deserializeMessage(message);
        } else {
            log.error("decode message found unknow message type {}, message is {}", messageType, message);
            throw new BusinessException(ExceptionCodes.MSG_FORMAT_INVALID);
        }

        // 执行消息完整性和正确性的检测
        if (!messageObj.selfValidate()) {
            throw new BusinessException(ExceptionCodes.MSG_NOT_COMPLETE);
        }

        return messageObj;
    }
}
